package study.chapter03.thread.model;

//生产者与消费者模型
public class TestThread2 {
    public static void main(String[] args) {
        Bread2 bread = new Bread2();
        new Thread(new Producer2(bread), "生产者线程").start();
        new Thread(new Consumer2(bread), "消费者线程").start();
    }
}

//面包类
class Bread2{
    private int id;
    private String name;
    private Boolean flag = true;
    //flag = true只允许生产
    //flag = false只允许消费

    //同步需要同步对象，将面包作为同步对象，所以把同步操作放在了面包类的方法中
    public synchronized void set(Integer id, String name){
        if (flag == false){     //不能生产，等待被消费
            try {
                super.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.id = id;
        this.name = name;
        try {
            Thread.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        this.flag = false;  //已经生产过了
        super.notify(); //唤起等待的线程
    }

    public synchronized String get(){
        if (this.flag){//还未生产
            try {
                super.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        try {
            return "消费面包：id=" + this.id + "，" + this.name;
        } finally {
            this.flag = true;
            super.notify();
        }
    }

    @Override
    public String toString() {
        return "Bread{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

//生产者
class Producer2 implements Runnable{
    private Bread2 bread;
    Producer2(Bread2 bread){
        this.bread = bread;
    }

    @Override
    public void run() {
        System.out.println("开始生产面包");
        for (int i = 1; i <= 10; i++) {
            bread.set(i, "面包" + i);
            System.out.println("生产面包：" + bread);

            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

//消费者
class Consumer2 implements Runnable{
    private Bread2 bread;
    Consumer2(Bread2 bread){
        this.bread = bread;
    }

    @Override
    public void run() {
        System.out.println("开始消费面包");
        for (int i = 0; i < 10; i++) {
            System.out.println(bread.get());
        }
    }
}
